/*
 * @LastEditTime: 2021-05-07 09:06:03
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \my_rust_test\my_rust\src\my_rust_rc_ac
*/
use std::rc::Rc;//单线程指针
use std::sync::Arc;//多线程指针
use std::thread;
pub fn run1() {
    /*

    Rc<T> - 引用计数智能指针
    允许一个值有多个所有者（只有访问权），通过引用计数来跟踪值的所有者数量。
    通过记录一个数据被引用的次数来确定该数据是否正在被使用。当引用次数归零时，就代表该数据不再被使用，因此可以被清理释放。

     

    */

    let a = Rc::new(5);//实际上就是一个用引用计数智能指针包裹住的 不可变引用（）
    let b  = Rc::clone(&a);
    println!("a-{}-", a);
    println!("b-{}-", b);

    
    let c = Rc::new(String::from("噜啦噜啦咧噜啦噜啦咧"));

    // let c= Rc::clone(&c);
    println!("c-{0}-{1}", c, Rc::strong_count(&c)); //Rc::strong_count(&c) 获取 引用过的次数
    println!("c-{0}-{1}", c, Rc::strong_count(&c));
    println!("c-{0}-{1}", c, Rc::strong_count(&c));
    {
        let cc = Rc::clone(&c);
        println!("c-{0}-{1}", c, Rc::strong_count(&cc));
    }
    let d = c.clone(); //深拷贝，拷贝所有内容
    let d = c.clone();
    println!("d-{}-{1}", d, Rc::strong_count(&d));
    let e = Rc::clone(&c); //浅拷贝，只拷贝指针地址
    let e = Rc::clone(&c);
    println!("e-{}-{1}", e, Rc::strong_count(&e));
}

pub fn run2() {
    let s = Rc::new(String::from("大王叫我来巡山"));
    println!("{}", s);
    let a = Rc::clone(&s); //复制一个指向s 的指针副本 是他们数据能够共享

    println!("{}", a);
    println!("{}", Rc::strong_count(&s));
    {
        /*
         因为 rc 实现了 drop 特征， 所以 当他离开作用域范围是会被释放，所以 引用计数器（Rc::strong_count） 会减1
        */

        let b = Rc::clone(&s); //作用域内复制一个指针副本
        println!("作用域内b {}", b);
        println!("作用域内 的底层引用计数为{}", Rc::strong_count(&s));
    }
    println!("离开作用域后{}", Rc::strong_count(&s));
}

pub fn run3() {

    let s = Arc::new(String::from("大王叫我来巡山"));//创建一个适用于异步的智能指针

    for i in 0..20{
        let  a = Arc::clone(&s);
        let handle = thread::spawn(move ||
            {
            println!("线程{0},{1},{2}",i, a,Arc::strong_count(&a));
            
        });
        
    }
    let b =Arc::clone(&s);

    //strong_count 不管你使用的那个指针副本入参， 他都会返回 该内存实际存在的 引用数
   println!("计数器{0},{1}",Arc::strong_count(&b),Arc::strong_count(&s));



}
pub fn run() {
    //run1();
    //run2();
    run3();
}
